﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Text;
using System.Threading.Tasks;

namespace SharpSoft.Maths
{
    /// <summary>
    /// 线条辅助算法
    /// </summary>
    public static class LineHelper
    {
        /// <summary>
        /// 计算两条直线的交点
        /// </summary>
        /// <param name="line1p1">L1的点1坐标</param>
        /// <param name="line1p2">L1的点2坐标</param>
        /// <param name="line2p1">L2的点1坐标</param>
        /// <param name="line2p2">L2的点2坐标</param>
        /// <returns></returns>
        public static Vector2 GetIntersection(Vector2 line1p1, Vector2 line1p2, Vector2 line2p1, Vector2 line2p2)
        {
            /*
             * L1，L2都存在斜率的情况：
             * 直线方程L1: ( y - y1 ) / ( y2 - y1 ) = ( x - x1 ) / ( x2 - x1 ) 
             * => y = [ ( y2 - y1 ) / ( x2 - x1 ) ]( x - x1 ) + y1
             * 令 a = ( y2 - y1 ) / ( x2 - x1 )
             * 有 y = a * x - a * x1 + y1   .........1
             * 直线方程L2: ( y - y3 ) / ( y4 - y3 ) = ( x - x3 ) / ( x4 - x3 )
             * 令 b = ( y4 - y3 ) / ( x4 - x3 )
             * 有 y = b * x - b * x3 + y3 ..........2
             * 
             * 如果 a = b，则两直线平行，否则， 联解方程 1,2，得:
             * x = ( a * x1 - b * x3 - y1 + y3 ) / ( a - b )
             * y = a * x - a * x1 + y1
             * 
             * L1存在斜率, L2平行Y轴的情况：
             * x = x3
             * y = a * x3 - a * x1 + y1
             * 
             * L1 平行Y轴，L2存在斜率的情况：
             * x = x1
             * y = b * x - b * x3 + y3
             * 
             * L1与L2都平行Y轴的情况：
             * 如果 x1 = x3，那么L1与L2重合，否则平行
             * 
            */
            Vector2 non = new Vector2(float.NaN);
            float a = 0, b = 0;
            int state = 0;
            if (line1p1.X != line1p2.X)
            {
                a = (line1p2.Y - line1p1.Y) / (line1p2.X - line1p1.X);
                state |= 1;
            }
            if (line2p1.X != line2p2.X)
            {
                b = (line2p2.Y - line2p1.Y) / (line2p2.X - line2p1.X);
                state |= 2;
            }
            switch (state)
            {
                case 0: //L1与L2都平行Y轴
                    {
                        if (line1p1.X == line2p1.X)
                        {
                            //throw new Exception("两条直线互相重合，且平行于Y轴，无法计算交点。");
                            return non;
                        }
                        else
                        {
                            //throw new Exception("两条直线互相平行，且平行于Y轴，无法计算交点。");
                            return non;
                        }
                    }
                case 1: //L1存在斜率, L2平行Y轴
                    {
                        float x = line2p1.X;
                        float y = (line1p1.X - x) * (-a) + line1p1.Y;
                        return new Vector2(x, y);
                    }
                case 2: //L1 平行Y轴，L2存在斜率
                    {
                        float x = line1p1.X;
                        //网上有相似代码的，这一处是错误的。你可以对比case 1 的逻辑 进行分析
                        //源code:lineSecondStar * x + lineSecondStar * lineSecondStar.X + p3.Y;
                        float y = (line2p1.X - x) * (-b) + line2p1.Y;
                        return new Vector2(x, y);
                    }
                case 3: //L1，L2都存在斜率
                    {
                        if (a == b)
                        {
                            // throw new Exception("两条直线平行或重合，无法计算交点。");
                            return new Vector2(0, 0);
                        }
                        float x = (a * line1p1.X - b * line2p1.X - line1p1.Y + line2p1.Y) / (a - b);
                        float y = a * x - a * line1p1.X + line1p1.Y;
                        return new Vector2(x, y);
                    }
            }
            // throw new Exception("不可能发生的情况");
            return non;
        }
    }
}
